package com.gearbox.platform.deadline.service;

import com.gearbox.core.configuration.SystemConfiguration;
import com.gearbox.core.constant.DeadlineInstanceStatusEnum;
import com.gearbox.core.constant.NodeStatusEnum;
import com.gearbox.core.model.Node;
import com.gearbox.core.service.NodeService;
import com.gearbox.platform.deadline.exception.MethodNotSupportException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

@Component
@ConditionalOnProperty(name = "system.type", havingValue = "deadline")
public class DeadlineNodeService implements NodeService {
    @Autowired
    private SystemConfiguration systemConfiguration;

    @Override
    public List<Node> listUnstableNodes() {
        return getSlaves().stream()
            .filter(node ->
                !systemConfiguration.getStableNodes().contains(node.getName()))
            .collect(Collectors.toList());
    }

    private List<Node> getSlaves() {
        return DeadlineCommandExecutor.getSlaveNames().parallelStream()
            .map(this::getSlave)
            .collect(Collectors.toList());
    }

    private Node getSlave(String slaveName) {
        String slaveStatus = DeadlineCommandExecutor.getSlaveStatusByName(slaveName);
        boolean isEnabled = DeadlineCommandExecutor.isSlaveEnabled(slaveName);
        return new Node(slaveName, NodeStatusEnum.toNodeStatus(DeadlineInstanceStatusEnum.value(slaveStatus)),
            isEnabled);
    }

    @Override
    public List<Node> listUnstableDrainNodes() {
        return getSlaves().stream()
            .filter(node ->
                !node.isEnabled()
                    && !node.getStatus().isAbnormal()
                    && !systemConfiguration.getStableNodes().contains(node.getName()))
            .collect(Collectors.toList());
    }

    @Override
    public List<Node> listUnstableIdleNodes() {
        return getSlaves().stream()
            .filter(node ->
                node.getStatus().equals(NodeStatusEnum.IDLE)
                    && !systemConfiguration.getStableNodes().contains(node.getName()))
            .collect(Collectors.toList());
    }

    @Override
    public void remove(Node node) {
        DeadlineCommandExecutor.deleteSlave(node.getName());
    }

    @Override
    public boolean isWorking(String nodeName) {
        return DeadlineCommandExecutor.getSlaveStatusByName(nodeName)
            .equalsIgnoreCase(DeadlineInstanceStatusEnum.RENDERING.name());
    }

    @Override
    public void setToDrain(String nodeName) {
        DeadlineCommandExecutor.disableSlave(nodeName);
    }

    @Override
    public int getUserNodeQuotas(String userName) {
        throw new MethodNotSupportException("deadline not support get quotas");
    }
}
